//
//  CommonExt.swift
//  imprint
//
//  Created by 小柠檬🍋 on 2025/4/6.
// 扩展方法
//

import Foundation



extension Array {
    //随机数组
    func getRandomSubList() -> [Element] {
        if self.isEmpty {
            return []
        }
        let randomSize = Int.random(in: 1...self.count)
        let shuffledArray = self.shuffled()
        return Array(shuffledArray.prefix(randomSize))
    }
    
    //随机数组
    func getRandomSubList(count: Int) -> [Element] {
        if self.isEmpty {
            return []
        }
        let shuffledList = shuffled()
        if count >= self.count {
            return Array(shuffledList)
        } else {
            return Array(shuffledList.prefix(count))
        }
    }
}

extension String {
    //cdn转换
    func formatCdn() -> String {
        if self.isEmpty {
            return ""
        }
        return convertCdn(self)
    }
}

extension String? {
    //cdn转换
    func formatCdn() -> String {
        if self == nil || self!.isEmpty {
            return ""
        }
        return convertCdn(self)
    }
    
    //转为版本号。如1.1.1 转为111
    func formatVersion() -> Int {
        if self == nil || self!.isEmpty {
            return 0
        }
        if let versionStr = self?.replacingOccurrences(of: ".", with: "") {
            let versiton = Int(versionStr)
            return versiton ?? 0
        }
        return 0
    }
    
    func formatAiChat(_ botRoleBean: RoleBean?, _ time: TimeInterval) -> String {
        return (self ?? "").formatAiChat(botRoleBean, time)
    }
}

extension String {
    
    func formatAiChatAll(_ botRoleBean: RoleBean, _ time: TimeInterval,
                         replace: String = "",
                         replaceStr: String = "")-> String {
        //动作描述
        let actionDescClose = !AppStorageManager.shared.toggleAiDesc ? "回复只输出最后的话语，不包括任何表情动作" : ""
        
        let botDesc =  RoleBean.getBotDesc(botRoleBean)
        let userDesc =  RoleBean.getUserDesc(botRoleBean)
        
        let memoryDesc = AppStorageManager.shared.toggleMemoryInject ? AiDescribeManager.shared.getConfig().aiMemoryInjectDesc?.formatAiChatContent(ActiveAIMemoryExt.instance.getAiMemoryStr(botRoleBean: botRoleBean)) ?? "" : ""
        
        
        //表情包规则，头部带n\n#
        let emojiPictureStr = AiChatExt.getEmojiPictureStr()//表情包
        //表情包回复规则
        let replyEmojiPictureReplyStr = emojiPictureStr.isEmpty ? "" : configManager.getConfig().getAiDescribe().emojiPictureReply ?? ""
        let emojiRule = emojiPictureStr + replyEmojiPictureReplyStr
        
        let rule = formatAiChat("{{botDesc}}", botDesc)
            .formatAiChat("{{userDesc}}", userDesc)
            .formatAiChat("{{memoryDesc}}", memoryDesc)
            .formatAiChat("{{emojiDesc}}", emojiRule)
            .formatAiChat("{{actionDesc}}", actionDescClose)
            .formatAiChat(replace, replaceStr)
            .formatAiChat(botRoleBean, time)
        //删除不匹配 {{}}
        return EmojiUtils.deleteNoEmotionContent2(text: rule) ?? ""
    }
    
    //ai 字符处理，时间要从外部传递进来，因为有时候是之前的，比如ai日记跟来信
    func formatAiChat(_ botRoleBean: RoleBean?, _ time: TimeInterval) -> String {
        let botName = botRoleBean?.name ?? ""
        let userName = botRoleBean?.name2 ?? ""
        //替换名字
        return self.replacingOccurrences(of: "{{bot}}", with: botName)
            .replacingOccurrences(of: "{{char}}", with: botName)
            .replacingOccurrences(of: "{{user}}", with: userName)
            .replacingOccurrences(of: "{{time}}", with: AiChatExt.getAiTime(time: time))
    }
    
    //内容替换
    func formatAiChatContent(_ text: String) -> String {
        return self.replacingOccurrences(of: "{{content}}", with: text)
    }
    
    //内容替换
    func formatAiChat(_ replace: String, _ text: String) -> String {
        return self.replacingOccurrences(of: replace, with: text)
    }
    
    //替换字符串中的随机数标记 {{数字}}{{random}}
    func replaceAiRandom() -> String {
        // 1/3 概率返回空字符串
        if Int.random(in: 0..<3) == 0 {
            return ""
        }
        
        do {
            let regex = try NSRegularExpression(pattern: "\\{\\{(\\d+)\\}\\}\\{\\{random\\}\\}")
            let nsString = self as NSString
            let result = nsString.mutableCopy() as! NSMutableString
            let matches = regex.matches(in: self, range: NSRange(location: 0, length: nsString.length))
            
            // 倒序处理匹配项，避免索引变化导致的问题
            for match in matches.reversed() {
                let wholeRange = match.range(at: 0)
                guard let max = Int(nsString.substring(with: match.range(at: 1))) else {
                    continue
                }
                
                // 生成 2~max 的随机数（包含边界）
                let minValue = 2
                if max >= minValue {
                    let randomValue = Int.random(in: minValue...max)
                    result.replaceCharacters(in: wholeRange, with: "\(randomValue)")
                }
            }
            
            return result as String
        } catch {
            showLog("正则表达式错误: \(error)")
            return self
        }
    }
    //将String分段成一个数组，如1.xxxx 2.xxxx进行分段
    func splitByNumberedSections() -> [String] {
        let pattern = #"\d+[、.)),;；。]\s*"#
        guard let regex = try? NSRegularExpression(pattern: pattern) else { return [self] }
        
        var sections = [String]()
        var currentIndex = self.startIndex // 改用 String.Index
        
        regex.enumerateMatches(in: self, range: NSRange(location: 0, length: utf16.count)) { match, _, _ in
            guard let match = match,
                  let range = Range(match.range, in: self) else { return }
            
            // 从 currentIndex 到分隔符起始位置的内容为一段
            if currentIndex < range.lowerBound {
                let segment = self[currentIndex..<range.lowerBound]
                sections.append(String(segment).trimmingCharacters(in: .whitespacesAndNewlines))
            }
            // 更新当前索引到分隔符结尾
            currentIndex = range.upperBound
        }
        
        // 添加剩余内容
        if currentIndex < endIndex {
            sections.append(String(self[currentIndex..<endIndex]).trimmingCharacters(in: .whitespacesAndNewlines))
        }
        
        return sections
    }
    
    //检测是否是url
    func isUrl() -> Bool {
        let urlString = self
        // 检查是否能创建URL实例
        guard let url = URL(string: urlString) else {
            return false
        }
        
        // 检查URL是否有有效的scheme和host
        guard url.scheme != nil, url.host != nil else {
            return false
        }
        
        // 使用NSDataDetector进行更严格的URL格式验证
        guard let detector = try? NSDataDetector(types: NSTextCheckingResult.CheckingType.link.rawValue) else {
            return false
        }
        
        let matches = detector.matches(in: urlString, options: [], range: NSRange(location: 0, length: urlString.utf16.count))
        return matches.count == 1 && matches.first?.range.location == 0 && matches.first?.range.length == urlString.utf16.count
    }
    
    //字符串提取json，括号计数法
    func extractJson() -> String? {
        // 找到第一个 JSON 起始符号（[ 或 {）
        guard let startIndex = self.firstIndex(where: { $0 == "[" || $0 == "{" }) else {
            return nil
        }
        
        let startChar = self[startIndex]
        let endChar: Character = startChar == "[" ? "]" : "}"
        
        var count = 0
        var currentIndex = startIndex
        
        // 遍历字符串计算括号平衡
        while currentIndex < self.endIndex {
            let char = self[currentIndex]
            
            if char == startChar {
                count += 1
            } else if char == endChar {
                count -= 1
            }
            
            // 当括号平衡时，提取子串
            if count == 0 {
                return String(self[startIndex...currentIndex])
            }
            
            currentIndex = self.index(after: currentIndex)
        }
        
        // 括号不匹配的情况
        return nil
    }
}

extension Double {
    func formatNumber() -> String {
        let price = self
        let formatter = NumberFormatter()
        formatter.numberStyle = .decimal
        formatter.minimumFractionDigits = 0
        formatter.maximumFractionDigits = 2
        return formatter.string(from: NSNumber(value: price)) ?? ""
    }
}

extension Date {
    func isSameDay(as other: Date) -> Bool {
        let calendar = Calendar.current
        return calendar.isDate(self, inSameDayAs: other)
    }
    
    func isYesterday() -> Bool {
        let calendar = Calendar.current
        let components = calendar.dateComponents([.year, .month, .day], from: self)
        let yesterdayComponents = calendar.date(byAdding: .day, value: -1, to: Date())!
        let yesterday = calendar.dateComponents([.year, .month, .day], from: yesterdayComponents)
        return components.year == yesterday.year && components.month == yesterday.month && components.day == yesterday.day
    }
    
    func isSameWeek(as other: Date) -> Bool {
        let calendar = Calendar.current
        let selfComponents = calendar.dateComponents([.yearForWeekOfYear, .weekOfYear], from: self)
        let otherComponents = calendar.dateComponents([.yearForWeekOfYear, .weekOfYear], from: other)
        return selfComponents.yearForWeekOfYear == otherComponents.yearForWeekOfYear && selfComponents.weekOfYear == otherComponents.weekOfYear
    }
    
    func isSameYear(as other: Date) -> Bool {
        let calendar = Calendar.current
        let selfComponents = calendar.dateComponents([.year], from: self)
        let otherComponents = calendar.dateComponents([.year], from: other)
        return selfComponents.year == otherComponents.year
    }
}

// UIImage扩展：转换为Base64
extension UIImage {
    func toBase64() -> String? {
        // 转换为JPEG格式并压缩
        guard let imageData = self.jpegData(compressionQuality: 0.8) else {
            return nil
        }
        return imageData.base64EncodedString()
    }
}
extension Int64 {
    //生成邀请码,10 亿以内
    func generateInviteCode() -> String {
        let id: Int64 = self
        let BASE_CHARS = "ABCDEFGHJKLMNPQRSTUVWXYZ23456789"
        let CODE_LENGTH = 6 // 邀请码长度
        
        // 1. 对ID进行哈希混淆（避免直接暴露ID）
        let hashedId = id.hashId()
        
        // 2. 转换为字符
        var result = ""
        var value = hashedId
        
        // 3. 每次取5位（32=2^5），映射到字符集
        for _ in 0..<CODE_LENGTH {
            let index = Int(value & 0x1F) // 取低5位（0-31）
            let charIndex = BASE_CHARS.index(BASE_CHARS.startIndex, offsetBy: index)
            result.append(BASE_CHARS[charIndex])
            value = value >> 5 // 右移5位处理下一组
        }
        
        return String(result.reversed()) // 反转使低位在前，分布更均匀
    }
    
    private func hashId() -> Int64 {
        let id = self
        var hash = id
        hash = hash ^ (hash >> 16)
        hash &*= 0x85ebca6b
        hash = hash ^ (hash >> 13)
        hash &*= 0xc2b2ae35
        hash = hash ^ (hash >> 16)
        return hash
    }
}
